package com.dyp.filterdemo.web.filter;

import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.*;

@Order(1)
//@Component
@WebFilter
public class FirstFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        Filter.super.init(filterConfig);
    }

    /*
    查看日志可以发现，SpringBoot已经帮我们注入了一个filter，拦截路径是/*，拦截所有，如果我们需要进一步拦截具体的则需要我们自己在代码里控制
     */
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        System.out.println("FirstFilter,"+request.getRequestURI());

        // 包装原始的Response对象
        CharResponseWrapper wrappedResponse = new CharResponseWrapper(response);

        filterChain.doFilter(servletRequest, wrappedResponse);

        // 获取原始响应内容
        String originalResponse = wrappedResponse.getResponseBody();

        // 在原始响应后添加一行数据
        String modifiedResponse = originalResponse + "\nAdded by Fist Filter";

        // 将修改后的内容写回原始Response
        response.setContentLength(modifiedResponse.length());  // 更新Content-Length
        response.getWriter().write(modifiedResponse);
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }

    // 自定义Response包装类
    private static class CharResponseWrapper extends HttpServletResponseWrapper {
        private final ByteArrayOutputStream bos;
        private final ServletOutputStream out;
        private final PrintWriter writer;

        public CharResponseWrapper(HttpServletResponse response) throws IOException {
            super(response);
            this.bos = new ByteArrayOutputStream();
            this.out = new ServletOutputStream() {
                @Override
                public boolean isReady() {
                    return true;
                }

                @Override
                public void setWriteListener(WriteListener writeListener) {

                }

                @Override
                public void write(int b) throws IOException {
                    bos.write(b);
                }

                @Override
                public void write(byte[] b) throws IOException {
                    bos.write(b);
                }
            };
            this.writer = new PrintWriter(out);
        }

        @Override
        public ServletOutputStream getOutputStream() throws IOException {
            return this.out;
        }

        @Override
        public PrintWriter getWriter()  {
            return this.writer;
        }
//        public PrintWriter getWriter()  {
//            return new PrintWriter(out);
//        }


        public String getResponseBody() throws IOException {
//            ServletOutputStream outputStream = this.getOutputStream();
//            outputStream.flush();

            PrintWriter writer = this.getWriter();
            writer.flush();

//            return bos.toString("UTF-8".toString());
            return bos.toString(this.getCharacterEncoding());

        }
    }
}
